﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Billing.WindowsBase;
using Billing.DataObjects;
using System.Reflection;
using Infragistics.Win.UltraWinGrid;

namespace Billing.Win
{
    public partial class TransactionsImportForm : BaseList
    {
        BillingDataContext mBillingDataContext = new BillingDataContext();
        bool mIsSaved = false;

        public TransactionsImportForm()
        {
            InitializeComponent();
            //mBillingDataContext.FileTypes
        }

        #region Local Variables

        List<FieldMapping> mFieldMapping = null;
        List<object> mObjects = null;
        TransType mCurrentTrynsType = null;
        FileType mCurrentFileType = null;
        #endregion

        private void frmTransactionsImport_Load(object sender, EventArgs e)
        {
            //TransTypeDB db = new TransTypeDB();
            //this.bsTransTypes.DataSource = db.getView();
            this.bsTransTypes.DataSource = mBillingDataContext.TransTypes;
        }

        public void LoadMapping()
        {
            if (mCurrentFileType != null)
            {
                IEnumerable<FieldMapping> fieldMapping = from n in mBillingDataContext.FieldMappings
                                                         where n.FileTypeID == this.mCurrentFileType.ID
                                                         select n;
                mFieldMapping = fieldMapping.ToList<FieldMapping>();
            }
            //fm = obj.getObjectsByFileType(this.CurrentFileType.ID);
        }

        private string GetFieldMappingProperties()
        {
            string retValue = String.Empty;
            foreach (FieldMapping fieldMapping in mFieldMapping)
            {
                if (fieldMapping.Active)
                    retValue = retValue + fieldMapping.FildExpression + ",";
            }
            return retValue.TrimEnd(",".ToCharArray());
        }

        private void frmTransactionsImport_ImportingFile(string FileName)
        {
            System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection();
            cn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FileName + @";Extended Properties=""Excel 8.0;IMEX=1""";
            PropertyInfo pi = null;
            try
            {
                this.LoadMapping();
                System.Data.OleDb.OleDbCommand cm = new System.Data.OleDb.OleDbCommand();
                cm.CommandText = string.Format("SELECT {0} FROM [Sheet1$]", GetFieldMappingProperties());
                cm.Connection = cn;
                mObjects = new List<object>();

                cn.Open();
                IDataReader dr = cm.ExecuteReader();

                while (dr.Read())
                {
                    if (dr[0] != DBNull.Value)
                    {
                        object doc = GetTypedObject(this.mCurrentTrynsType.ObjectType);

                        foreach (FieldMapping obj in this.mFieldMapping)
                        {
                            if (String.IsNullOrEmpty(obj.RegExp) == false)
                            {
                                System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(obj.RegExp);
                                string str = dr[obj.FildName.TrimStart('[').TrimEnd(']')].ToString();
                                if (!re.IsMatch(str))
                                    throw new Exception(string.Format("{0} სტრიქონზე  {1} ველში ({2}) მონაცემის ფორმატი არასწორია", mObjects.Count.ToString(), obj.FildName, str));
                            }

                            pi = doc.GetType().GetProperty(obj.Key,
                                BindingFlags.FlattenHierarchy
                                | BindingFlags.IgnoreCase
                                | BindingFlags.SetProperty
                                | BindingFlags.Public
                                | BindingFlags.Instance
                                );
                            if (obj.Active)
                            {
                                if (dr[obj.FildName.TrimStart('[').TrimEnd(']')] != DBNull.Value)
                                    pi.SetValue(doc, Convert.ChangeType(dr[obj.FildName.TrimStart('[').TrimEnd(']')], System.Type.GetType(obj.FieldType)), null);
                            }
                            else
                                pi.SetValue(doc, Convert.ChangeType(obj.FieldDefaultValue, System.Type.GetType(obj.FieldType)), null);
                        }

                        mObjects.Add(doc);
                    }
                }
                this.bsElement.DataSource = mObjects;
                GridLeyaout();
                mIsSaved = false;
            }
            catch (Exception ex)
            {
                string str = string.Empty;
                if (pi != null)
                    str = pi.Name;
                MessageBox.Show(ex.Message + "\n " + mObjects.Count + "\n ველი: " + str);
                this.mObjects = null;
            }
            finally
            {
                if (cn.State != ConnectionState.Closed)
                    cn.Close();
            }
        }

        private FieldMapping GetFieldMappingByFildName(string fildName)
        {
            foreach (FieldMapping fm in mFieldMapping)
            {
                if (fm.FildName == fildName)
                    return fm;
            }
            return null;
        }

        private void GridLeyaout()
        {
            this.grd.DisplayLayout.Bands[0].Summaries.Clear();
            foreach (Infragistics.Win.UltraWinGrid.UltraGridColumn var in this.grd.DisplayLayout.Bands[0].Columns)
            {
                FieldMapping fieldMapping = GetFieldMappingByFildName(var.Key);
                if (fieldMapping != null)
                {
                    var.Header.Caption = fieldMapping.FieldCaption;
                    var.Header.VisiblePosition = fieldMapping.FieldPosition;
                    var.CellAppearance.FontData.Name = fieldMapping.FieldFont;
                    var.Width = (int)fieldMapping.FieldWidth;
                    if (fieldMapping.FieldFormat != null)
                        var.Format = fieldMapping.FieldFormat;
                    if (fieldMapping.FieldSummary)
                    {
                        var.CellAppearance.TextHAlign = Infragistics.Win.HAlign.Right;

                        var.Band.Summaries.Add(var.Key,
                            SummaryType.Sum,
                            null,
                            var,
                            SummaryPosition.UseSummaryPositionColumn,
                            var);
                        var.Band.Summaries[var.Key].DisplayFormat = "{0:#,#0.00}";
                    }
                    if (fieldMapping.Active)
                        var.Hidden = false;
                    else
                        var.Hidden = true;
                }
                else
                    if (var.Key.ToLower() == "completed")
                        var.Hidden = false;
                    else
                        var.Hidden = true;
            }
        }

        protected override void onSave()
        {
            if (mIsSaved)
            {
                ShowInformation("მონაცემები უკვე შენახულია, ჩატვირთეთ ახალი მონაცმები.");
                return;
            }
            base.onSave();
            try
            {
                if (this.mObjects == null || this.mObjects.Count == 0)
                    throw new Exception("მონაცემები არ არის ჩატვირთული");
                this.Cursor = Cursors.WaitCursor;

                BeforeDocsAdd();
                if (mObjects[0] is PaymentOrder)
                    TransferPaymentOrder();
                mIsSaved = true;
                ShowInformation("მონაცემების შენახვა დასრულებულია.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void TransferPaymentOrder()
        {
            foreach (PaymentOrder paymentOrder in mObjects.Cast<PaymentOrder>())
            {
                try
                {
                    mBillingDataContext.PaymentOrders.InsertOnSubmit(paymentOrder);
                }
                catch (Exception ex)
                {
                    if (this.chkCompleteOnError.Checked)
                    {
                        continue;
                    }
                    else
                    {
                        MessageBox.Show(ex.Message);
                        break;
                    }
                }
            }
            mBillingDataContext.SubmitChanges();

        }


        void BeforeDocsAdd()
        {
            Billing.DataObjects.File file = new Billing.DataObjects.File();
            mBillingDataContext.Files.InsertOnSubmit(file);

            file.FileTypeID = 1;
            file.Key = System.IO.Path.GetFileNameWithoutExtension(this.ImportedFileName);
            file.Name = this.ImportedFileName;

            foreach (object doc in mObjects)
            {
                PropertyInfo pi = doc.GetType().GetProperty("File",
                                                BindingFlags.FlattenHierarchy
                                                | BindingFlags.IgnoreCase
                                                | BindingFlags.SetProperty
                                                | BindingFlags.Public
                                                | BindingFlags.Instance
                                                );
                pi.SetValue(doc, file, null);
            }
        }

        private void cmbTransType_ValueChanged(object sender, EventArgs e)
        {
            this.mCurrentTrynsType = null;
            if (this.cmbTransType.Value != null)
            {
                this.mCurrentTrynsType = (TransType)this.bsTransTypes.Current;
                this.bsFileTypes.DataSource = from n in mBillingDataContext.FileTypes
                                              where n.TransTypeID == mCurrentTrynsType.ID
                                              select n;
            }
        }

        private void cmbFileTypes_ValueChanged(object sender, EventArgs e)
        {
            this.mCurrentFileType = null;
            if (this.cmbFileTypes.Value != null)
            {
                this.mCurrentFileType = (FileType)this.bsFileTypes.Current;
            }
            this.bsElement.DataSource = null;
            this.mObjects = null;
        }

        private T CheckNull<T>(object val)
        {
            if (val == DBNull.Value)
                return default(T);
            else
                return (T)val;
        }

        private static object GetTypedObject(string Name)
        {
            return Activator.CreateInstance(System.Reflection.Assembly.GetAssembly(typeof(TransType)).FullName, Name).Unwrap();
        }
    }
}
